/*
 * Copyright (c) 2005, 2014 vacoor
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 */
package org.vacoor.nothing.plugin.impl;

import org.vacoor.nothing.common.reflect.GenericBeanSupport;
import org.vacoor.nothing.plugin.Plugin;
import org.vacoor.nothing.plugin.PluginManager;
import org.vacoor.nothing.plugin.StoragePlugin;

import java.io.File;
import java.lang.reflect.Array;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
import java.util.ServiceLoader;

/**
 * @author vacoor
 */
public class AbstractPluginManager<P extends Plugin> extends GenericBeanSupport<P> implements PluginManager<P> {
    protected final Class<P> pluginType;
    private ServiceLoader<P> plugins;

    protected AbstractPluginManager() {
        pluginType = getActualTypeArgument();
    }

    @Override
    public P[] getInstalled() {
        List<P> plugins = new ArrayList<P>();
        for (P plugin : this.plugins) {
            plugins.add(plugin);
        }
        P[] ps = (P[]) Array.newInstance(pluginType, plugins.size());
        return plugins.toArray(ps);
    }

    List<P> getAllPlugins() throws MalformedURLException {
        List<P> allPlugins = new ArrayList<P>();
        refreshPlugins();
        if (null != pluginClassLoader) {
            plugins = ServiceLoader.load(pluginType, pluginClassLoader);
            for (P p : plugins) {
                allPlugins.add(p);
            }
        }
        return allPlugins;
    }

    ClassLoader pluginClassLoader;

    void refreshPlugins() throws MalformedURLException {
        File file = new File("/Users/vacoor/lib");
        /*
        if (file.exists() && file.isDirectory()) {
            File[] files = file.listFiles(new FilenameFilter() {
                @Override
                public boolean accept(File file, String s) {
                    return s.endsWith(".jar");
                }
            });
            URL[] urls = new URL[files.length];
            for (int i = 0; i < urls.length; i++) {
                urls[i] = files[i].toURI().toURL();
            }
            pluginClassLoader = new URLClassLoader(urls, getClass().getClassLoader());
//            pluginClassLoader = new URLClassLoader(urls, null);
        }
        */
        pluginClassLoader = new URLClassLoader(new URL[]{file.toURI().toURL()}, getClass().getClassLoader());
    }

    public static void main(String[] args) throws MalformedURLException {
        AbstractPluginManager p = new AbstractPluginManager<StoragePlugin>() {
        };
        List<StoragePlugin> allPlugins = p.getAllPlugins();
        for (StoragePlugin allPlugin : allPlugins) {
            System.out.println(allPlugin.getName());
        }
        System.out.println();
    }

    public static void reload(AbstractPluginManager<StoragePlugin> p) throws MalformedURLException {
        List<StoragePlugin> allPlugins = p.getAllPlugins();
        for (StoragePlugin allPlugin : allPlugins) {
            System.out.println(allPlugin.getName());
        }
    }
}
